#include "tfBondDataCenter.h"
#include "BondFuture.h"
#include "tfBondInfo.h"
#include <qbkernel/include/qb_base.h>
#include <qbprotocol/include/rdProto.h>
#include <qbprotocol/include/SSMsgStruct.h>
#include <qbtools/message/MessagePoster.h>
#include <msgcenter/TFMsgProcess.h>

TFBondDataCenter& TFBondDataCenter::instance()
{
	static TFBondDataCenter s_bd;
	return s_bd;
}

void TFBondDataCenter::requestTFContactInfo()
{
	QBTFContactInfoReq_t req;
	FIELDCOPY(req.m_Version, "2.0");
	QBTFContactInfoReq_t* ptr = &req;

	qb::SSRequestMsg msg;
	msg.m_FuncID = E_FID_QB_TF_CONTACT_INFO_REQ;
	msg.m_pRequest = (void*)ptr;
	MessagePoster poster(&msg, qbmsg::tf::EncodeFunc);
 	poster.send(this);
}

void TFBondDataCenter::requestTFRefBond()
{
	CFutureArray ary;
	CBondFuture::instance().GetFutureArray(ary);
	for (auto it = ary.m_data.begin(); it != ary.m_data.end(); it++){
		qb::SSRequestMsg msg;
		msg.m_FuncID = E_FID_QB_TF_REFBOND_REQ;
		CFutureInfo& info = *it;
		QBRefBondReq_t req;
		FIELDCOPY(req.m_TF_Key, info.GetFutureKey());
		msg.m_pRequest = (void*)(&req);
		MessagePoster poster(&msg, qbmsg::tf::EncodeFunc);
		poster.send(this);
	}
}

void TFBondDataCenter::onDataArrived(const qb::SSAckMsg& msg)
{
	int funcId = msg.m_FuncID;
	if (funcId == E_FID_QB_TF_CONTACT_INFO_REQ) {
		xQBTFContactInfoList_c* pdata = (xQBTFContactInfoList_c*)msg.m_pRet;
		if (!pdata) return;
		const size_t size = pdata->m_List.size();
		if (size == 0) return;
		CBondFuture::instance().SetChangeDate(pdata->m_NatChangeDate);
		CFutureInfo info;
		for (std::list<xQBTFContactInfo_c>::const_iterator it = pdata->m_List.begin(); it != pdata->m_List.end(); ++it) {
			memset(&info, 0, sizeof(xQBTFContactInfo_c));
			FIELDCOPY(info.m_TF_Key, it->m_TF_Key);
			FIELDCOPY(info.m_TF_ID, it->m_TF_ID);
			info.m_Delivery_Month = it->m_Delivery_Month;
			info.m_Last_Trading_Day = it->m_Last_Trading_Day;
			info.m_Delivery_Date = it->m_Delivery_Date;
			info.m_BondTerm = it->m_BondTerm;
			info.m_Deliverable_maturity_Start = it->m_Deliverable_maturity_Start;
			info.m_Deliverable_maturity_End = it->m_Deliverable_maturity_End;
			FIELDCOPY(info.m_Quoted_Way, it->m_Quoted_Way);
			info.m_Min_Change = it->m_Min_Change;
			FIELDCOPY(info.m_Trading_Time, it->m_Trading_Time);
			FIELDCOPY(info.m_Last_Day_Trading_Time, it->m_Last_Day_Trading_Time);
			info.m_Price_Limit = it->m_Price_Limit;
			info.m_Lowest_Margins = it->m_Lowest_Margins;
			FIELDCOPY(info.m_Delivery_Way, it->m_Delivery_Way);
			FIELDCOPY(info.m_Listed_Market, it->m_Listed_Market);
			FIELDCOPY(info.m_Is_Tradable, it->m_Is_Tradable);
			CBondFuture::instance().Add(info);
		}
		if (msg.m_IsReceving == 0) {
			requestTFRefBond();
			emit recvData(funcId);
		}
	}
	else if (funcId == E_FID_QB_TF_REFBOND_REQ) {
		xQBRefBondList_c* pdata = (xQBRefBondList_c*)msg.m_pRet;
		if (!pdata) return;
		std::list<xQBRefBond_c>::const_iterator it = pdata->m_List.begin();
		for (; it != pdata->m_List.end(); it++) {
			CFutureRefBond::instance().Add(*it);
		}
		if (msg.m_IsReceving == 0) {
			emit recvData(funcId);
		}
	}
}

TFBondDataCenter::TFBondDataCenter()
{
	qbmsg::tf::InitDecodeFuncs();
}
